package com.zlzlib.okhttp.utils;

import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import org.springframework.context.annotation.Bean;

import java.net.URLDecoder;
import java.util.concurrent.TimeUnit;

/**
 * 日志初始化器  需要继承实现
 *
 * @DateTime: 2023/8/23 16:43
 * @Author zlz
 * @Version 1.0
 */
public abstract class BaseOkHttpConfig {

    @Bean
    public OkHttpClient okHttpClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        Dispatcher dispatcher = new Dispatcher();
        // 最大并发请求数
        dispatcher.setMaxRequests(maxRequests());
        // 每个主机最大并发请求数
        dispatcher.setMaxRequestsPerHost(maxRequestsPerHost());
        //连接超时
        builder.connectTimeout(connectTimeOut(), TimeUnit.SECONDS)
                //读取超时
                .readTimeout(readTimeOut(), TimeUnit.SECONDS)
                .writeTimeout(writeTimeOut(), TimeUnit.SECONDS)
                //设置最大空闲连接数为x，每个连接的最大请求数为5，空闲连接的最大存活时间为x秒
                .connectionPool(new ConnectionPool(maxIdleConnection(), keepAliveDuration(), TimeUnit.SECONDS))
                .dispatcher(dispatcher)
                .addInterceptor(log());
        initOkHttpClient(builder);
        return builder.build();
    }

    protected HttpLoggingInterceptor log() {
        //日志拦截器
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(s -> {
            //post 的请求体数据会转码 ， 这里日志进行一次解码  方便观看
            try {
                s = URLDecoder.decode(s, "UTF-8");
            } catch (Exception e) {
                e.printStackTrace();
            }
            logPrint(s);
        });
        //setlevel用来设置日志打印的级别，共包括了四个级别：NONE,BASIC,HEADER,BODY
        //BASEIC:请求/响应行
        //HEADER:请求/响应行 + 头
        //BODY:请求/响应行 + 头 + 体
        logInterceptor.level(HttpLoggingInterceptor.Level.BODY);
        return logInterceptor;
    }

    protected void initOkHttpClient(OkHttpClient.Builder builder) {
    }

    /**
     * 连接超时时间 秒
     */
    protected long connectTimeOut() {
        return 10;
    }

    /**
     * 读取超时时间 秒
     */
    protected long readTimeOut() {
        return 10;
    }

    /**
     * 写入超时时间 秒
     */
    protected long writeTimeOut() {
        return 10;
    }

    /**
     * 最大空闲连接数
     */
    protected int maxIdleConnection() {
        return 10;
    }

    /**
     * 闲连接的最大存活时间 秒
     */
    protected long keepAliveDuration() {
        return 60;
    }

    /**
     * 最大并发请求数
     */
    protected int maxRequests() {
        return 64;
    }

    /**
     * 每个主机最大并发请求数
     */
    protected int maxRequestsPerHost() {
        return 8;
    }

    /**
     * 日志打印
     *
     * @param log 日志
     */
    protected abstract void logPrint(String log);
}
